package com.kevin.mybatis.configuration.datascope.util;

import net.sf.jsqlparser.expression.*;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.InExpression;
import net.sf.jsqlparser.expression.operators.relational.ItemsList;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.select.FromItem;
import net.sf.jsqlparser.statement.select.PlainSelect;

import java.io.Serializable;
import java.util.List;
import java.util.stream.Collectors;

public class DataScopeUtil {

    public static Expression inExpression(Expression where, String tableName, String field, List<Serializable> ids) {
        ItemsList idList = new ExpressionList(ids.stream().map(DataScopeUtil::getValue).collect(Collectors.toList()));
        Expression inExpression = new InExpression(new Column(tableName + "." + field), idList);
        return new AndExpression(where, inExpression);
    }

    public static Expression equalsExpression(Expression where, String tableName, String field, List<Serializable> ids) {
        EqualsTo equalsTo = new EqualsTo();
        equalsTo.setLeftExpression(new Column(tableName + "." + field));
        equalsTo.setRightExpression(getValue(ids.getFirst()));
        return new AndExpression(where, equalsTo);
    }

    public static Expression all(Expression where) {
        return new AndExpression(where, new HexValue(" 1 = 1 "));
    }

    public static Expression getValue(Serializable value) {
        if (value instanceof Long || value instanceof Integer) {
            return new LongValue(value.toString());
        }
        return new StringValue(value.toString());
    }

    public static String getTableName(PlainSelect plainSelect) {
        FromItem fromItem = plainSelect.getFromItem();
        // 有别名用别名，无别名用表名，防止字段冲突报错
        Alias fromItemAlias = fromItem.getAlias();
        if (null != fromItemAlias) {
            return fromItemAlias.getName();
        }
        if (fromItem instanceof Table) {
            return ((Table) fromItem).getName();
        }
        return null;
    }

    public static Expression noData(Expression where) {
        // 使用一个永远不成立的条件，确保不返回任何数据
        return new AndExpression(where, new HexValue(" 1 = 2 "));
    }

}
